package com.smartum.mpr.client.view;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.smartgwt.client.data.RecordList;
import com.smartgwt.client.widgets.Canvas;
import com.smartgwt.client.widgets.IButton;
import com.smartgwt.client.widgets.events.ClickEvent;
import com.smartgwt.client.widgets.events.ClickHandler;
import com.smartgwt.client.widgets.grid.ListGrid;
import com.smartgwt.client.widgets.grid.ListGridField;
import com.smartgwt.client.widgets.grid.ListGridRecord;
import com.smartgwt.client.widgets.grid.events.CellClickEvent;
import com.smartgwt.client.widgets.grid.events.CellClickHandler;
import com.smartgwt.client.widgets.grid.events.EditCompleteEvent;
import com.smartgwt.client.widgets.grid.events.EditCompleteHandler;
import com.smartgwt.client.widgets.layout.HLayout;
import com.smartgwt.client.widgets.layout.VLayout;
import com.smartum.mpr.client.presenter.ItemsViewerPresenter;
import com.smartum.mpr.client.services.ItemsService;
import com.smartum.mpr.client.services.ItemsServiceAsync;
import com.smartum.mpr.shared.Category;
import com.smartum.mpr.shared.Subcategory;

import java.util.List;

/**
 */
public class ItemsViewer extends VLayout implements ItemsViewerPresenter.Display {
    final ListGrid itemsListGrid;
    final ListGrid subItemsListGrid;
    List<Category> storedCategories;

    public ItemsViewer() {
        GWT.log("[CONSTRUCT COMPONENT] items");

        HLayout itemsUpdateLayout = new HLayout(10);
        itemsUpdateLayout.setHeight100();
        itemsUpdateLayout.setWidth100();

        VLayout itemGrid = new VLayout();
        itemsListGrid = new ListGrid();
        itemsListGrid.setHeight100();
        itemsListGrid.setShowAllRecords(true);
        itemsListGrid.setShowEmptyMessage(true);
        itemsListGrid.setEmptyMessage("There's no items to display");

        ListGridField nameField = new ListGridField("name", "Categories");
        itemsListGrid.setFields(nameField);
        itemsListGrid.setShowHeader(false);
        itemsListGrid.setCanEdit(true);
        itemsListGrid.addCellClickHandler(new CellClickHandler() {
            public void onCellClick(CellClickEvent event) {
                final ListGridRecord selectedRecord = itemsListGrid.getSelectedRecord();
                final String id = selectedRecord.getAttribute("id");

                for (Category category : storedCategories) {

                    if (id.equals(category.getCategoryId().toString())) {
                        updateSubgrid(category.getSubcategories());
                    }
                }
            }
        });
        itemsListGrid.addEditCompleteHandler(new EditCompleteHandler() {
            public void onEditComplete(final EditCompleteEvent event) {

                final MaskPanel maskPanel = new MaskPanel();
                maskPanel.show();
                final ListGridRecord record = itemsListGrid.getRecord(event.getRowNum());
                final String id = record.getAttribute("id");
                if (id != null && !id.isEmpty()) {
                    final String name = record.getAttribute("name");
                    final ItemsServiceAsync itemsServiceAsync = GWT.create(ItemsService.class);
                    itemsServiceAsync.editCategory(id, name, new AsyncCallback<List<Category>>() {
                        public void onFailure(Throwable caught) {
                            maskPanel.hide();
                            maskPanel.destroy();
                        }

                        public void onSuccess(List<Category> result) {
                            storedCategories = result;
                            updateGrids(result);
                            itemsListGrid.selectRecord(event.getRowNum());
                            final List<Subcategory> subcategories = result.get(event.getRowNum()).getSubcategories();
                            updateSubgrid(subcategories);
                            if (subcategories.size() != 0) {
                                subItemsListGrid.selectRecord(0);
                            }
                            maskPanel.hide();
                            maskPanel.destroy();
                        }
                    });
                } else {
                    addNewCategory(event, record, maskPanel);
                }
            }
        });

        itemGrid.addMember(itemsListGrid);

        VLayout itemControls = new VLayout(5);
        itemControls.setWidth(120);

        IButton addNewCategory = new IButton("Add category");
        addNewCategory.setWidth(120);
        addNewCategory.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                itemsListGrid.startEditingNew();
            }
        });
        IButton deleteCategory = new IButton("Delete category");
        deleteCategory.setWidth(120);
        deleteCategory.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                final ItemsServiceAsync itemsServiceAsync = GWT.create(ItemsService.class);
                final ListGridRecord selectedRecord = itemsListGrid.getSelectedRecord();
                itemsServiceAsync.deleteCategory(selectedRecord.getAttribute("id"), new AsyncCallback<List<Category>>() {
                    public void onFailure(Throwable caught) {
                        //To change body of implemented methods use File | Settings | File Templates.
                    }

                    public void onSuccess(List<Category> result) {
                        storedCategories = result;
                        updateGrids(result);

                        if (result.size() != 0) {
                            updateSubgrid(result.get(0).getSubcategories());
                        }
                        itemsListGrid.selectRecord(0);
                    }
                });
            }
        });
        itemControls.addMember(addNewCategory);
        //itemControls.addMember(deleteCategory);

        VLayout subItemGrid = new VLayout();

        VLayout subItemControls = new VLayout(5);
        subItemControls.setWidth(120);
        IButton addNewSubCategory = new IButton("Add Subcategory");
        addNewSubCategory.setWidth(120);
        addNewSubCategory.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                subItemsListGrid.startEditingNew();
            }
        });
        IButton deleteSubCategory = new IButton("Delete Subcategory");
        deleteSubCategory.setWidth(120);
        deleteSubCategory.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                final ItemsServiceAsync itemsServiceAsync = GWT.create(ItemsService.class);
                final ListGridRecord selectedRecord = subItemsListGrid.getSelectedRecord();
                final int selectedRecordIndex = itemsListGrid.getRecordIndex(itemsListGrid.getSelectedRecord());
                if (selectedRecord == null) {
                    return;
                }
                itemsServiceAsync.deleteSubCategory(selectedRecord.getAttribute("id"), new AsyncCallback<List<Category>>() {
                    public void onFailure(Throwable caught) {
                    }

                    public void onSuccess(List<Category> result) {
                        storedCategories = result;

                        if (result.size() != 0 && result.get(selectedRecordIndex).getSubcategories().size() != 0) {
                            updateSubgrid(result.get(selectedRecordIndex).getSubcategories());
                            subItemsListGrid.selectRecord(0);
                        }
                    }
                });
            }
        });
        subItemControls.addMember(addNewSubCategory);
        //subItemControls.addMember(deleteSubCategory);

        subItemsListGrid = new ListGrid();
        subItemsListGrid.setHeight100();
        subItemsListGrid.setShowAllRecords(true);
        subItemsListGrid.setShowEmptyMessage(true);
        subItemsListGrid.setShowHeader(false);
        subItemsListGrid.setCanEdit(true);
        subItemsListGrid.setEmptyMessage("There's no subitems to display");

        subItemsListGrid.addEditCompleteHandler(new EditCompleteHandler() {
            public void onEditComplete(final EditCompleteEvent event) {

                final ListGridRecord record = subItemsListGrid.getRecord(event.getRowNum());
                final String id = record.getAttribute("id");
                final ListGridRecord categoryRecord = itemsListGrid.getSelectedRecord();
                final int selectedRecordIndex = itemsListGrid.getRecordIndex(categoryRecord);
                if (id != null && !id.isEmpty()) {
                    final String name = record.getAttribute("name");

                    final ItemsServiceAsync itemsServiceAsync = GWT.create(ItemsService.class);
                    itemsServiceAsync.editSubCategory(id, name, new AsyncCallback<List<Category>>() {
                        public void onFailure(Throwable caught) {
                        }

                        public void onSuccess(List<Category> result) {
                            storedCategories = result;
                            if (result.size() != 0 && result.get(selectedRecordIndex).getSubcategories().size() != 0) {
                                updateSubgrid(result.get(selectedRecordIndex).getSubcategories());
                                subItemsListGrid.selectRecord(0);
                            }
                        }
                    });
                } else {
                    addNewSubcategory(event, record, categoryRecord.getAttribute("id"), selectedRecordIndex);
                }
            }
        });

        ListGridField subcatigoryNameField = new ListGridField("name", "Subcategories");
        subItemsListGrid.setFields(subcatigoryNameField);
        subItemGrid.addMember(subItemsListGrid);

        final ItemsServiceAsync itemsServiceAsync = GWT.create(ItemsService.class);
        itemsServiceAsync.getCategories(new AsyncCallback<List<Category>>() {
            public void onFailure(Throwable caught) {
            }

            public void onSuccess(List<Category> result) {
                storedCategories = result;
                updateGrids(result);

                if (result.size() != 0) {
                    updateSubgrid(result.get(0).getSubcategories());
                }
                itemsListGrid.selectRecord(0);
            }
        });

        itemsUpdateLayout.addMember(itemGrid);
        itemsUpdateLayout.addMember(itemControls);
        itemsUpdateLayout.addMember(subItemGrid);
        itemsUpdateLayout.addMember(subItemControls);

        addMember(itemsUpdateLayout);
    }

    private void addNewCategory(final EditCompleteEvent event, ListGridRecord record, final MaskPanel maskPanel) {
        final String name = record.getAttribute("name");
        if (name != null && !name.isEmpty()) {
            final ItemsServiceAsync itemsServiceAsync = GWT.create(ItemsService.class);
            itemsServiceAsync.addCategory(name, new AsyncCallback<List<Category>>() {
                public void onFailure(Throwable caught) {
                    maskPanel.hide();
                    maskPanel.destroy();
                }

                public void onSuccess(List<Category> result) {
                    storedCategories = result;
                    updateGrids(result);
                    itemsListGrid.selectRecord(event.getRowNum());
                    updateSubgrid(result.get(result.size() - 1).getSubcategories());
                    maskPanel.hide();
                    maskPanel.destroy();
                }
            });
        } else {
            itemsListGrid.removeData(record);
        }
    }

    private void addNewSubcategory(final EditCompleteEvent event, ListGridRecord record, String id, final int selectedRecordIndex) {
        final String name = record.getAttribute("name");
        if (name != null && !name.isEmpty()) {
            final ItemsServiceAsync itemsServiceAsync = GWT.create(ItemsService.class);
            itemsServiceAsync.addSubCategory(id, name, new AsyncCallback<List<Category>>() {
                public void onFailure(Throwable caught) {
                }

                public void onSuccess(List<Category> result) {
                    storedCategories = result;
                    if (result.size() != 0 && result.get(selectedRecordIndex).getSubcategories().size() != 0) {
                        updateSubgrid(result.get(selectedRecordIndex).getSubcategories());
                        subItemsListGrid.selectRecord(0);
                    }
                }
            });
        } else {
            itemsListGrid.removeData(record);
        }
    }

    private void updateGrids(List<Category> result) {
        final RecordList recordList = new RecordList();
        for (Category category : result) {
            final ListGridRecord record = new ListGridRecord();
            record.setAttribute("id", category.getCategoryId());
            record.setAttribute("name", category.getCategoryName());

            recordList.add(record);
        }
        itemsListGrid.setData(recordList);
    }

    private void updateSubgrid(List<Subcategory> result) {
        final RecordList recordList = new RecordList();
        for (Subcategory subcategory : result) {
            final ListGridRecord record = new ListGridRecord();
            record.setAttribute("id", subcategory.getSubCategoryId());
            record.setAttribute("name", subcategory.getSubCategoryName());

            recordList.add(record);
        }
        subItemsListGrid.setData(recordList);
    }

    @Override
    public Canvas getItemsViewerWidget() {
        return this;
    }
}
